#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include <unistd.h>
#include <sys/time.h>
#include <sched.h>

#define NUM_TESTS 100  // 测试次数
#define SLEEP_TIME 10000  // 高优先级线程休眠时间，单位：毫秒

// 记录最大延迟
long long max_delay = 0;
int stop_low_priority_thread = 0; // 低优先级线程退出标志

// 用于计算时间差（微秒）
long long get_time_diff(struct timeval start, struct timeval end) {
    return (end.tv_sec - start.tv_sec) * 1000000 + (end.tv_usec - start.tv_usec);
}

// 高优先级线程的函数
void *high_priority_task(void *arg) {
    struct timeval start_time, wake_time;
    
    for (int i = 0; i < NUM_TESTS; i++) {
        // 记录当前时间，表示任务开始
        gettimeofday(&start_time, NULL);
        
        // 高优先级任务休眠10毫秒
        usleep(SLEEP_TIME); // usleep参数是微秒
        
        // 记录休眠结束时间，表示抢占成功后任务恢复
        gettimeofday(&wake_time, NULL);
        
        // 计算延迟
        long long delay = get_time_diff(start_time, wake_time);
        //记录的时间为开始时间
        
        // 更新最大延迟
        if (delay > max_delay) {
            max_delay = delay;
        }
    }

    // 高优先级线程执行完毕后设置退出标志
    stop_low_priority_thread = 1;

    return NULL;
}

// 低优先级线程的函数
void *low_priority_task(void *arg) {
    while (!stop_low_priority_thread) {
        // 模拟负载并允许 CPU 进行调度
        sched_yield();  // 让出 CPU 使得高优先级线程有机会运行
    }
    
    return NULL;
}

int main() {
    pthread_t high_thread, low_thread;
    struct sched_param high_param, low_param;

    // 设置高优先级线程
    high_param.sched_priority = sched_get_priority_max(SCHED_RR); // 高优先级
    // 设置低优先级线程
    low_param.sched_priority = sched_get_priority_min(SCHED_RR); // 低优先级

    // 创建高优先级线程
    if (pthread_create(&high_thread, NULL, high_priority_task, NULL) != 0) {
        perror("Failed to create high priority thread");
        return 1;
    }
    
    // 创建低优先级线程
    if (pthread_create(&low_thread, NULL, low_priority_task, NULL) != 0) {
        perror("Failed to create low priority thread");
        return 1;
    }

    // 设置高优先级线程的调度策略和优先级
    if (pthread_setschedparam(high_thread, SCHED_RR, &high_param) != 0) {
        perror("Failed to set high priority thread scheduling");
        return 1;
    }

    // 设置低优先级线程的调度策略和优先级
    if (pthread_setschedparam(low_thread, SCHED_RR, &low_param) != 0) {
        perror("Failed to set low priority thread scheduling");
        return 1;
    }

    // 等待两个线程结束
    pthread_join(high_thread, NULL);
    pthread_join(low_thread, NULL);

    // 输出最大延迟
    printf("Maximum task preemption delay: %lld microseconds\n", max_delay);

    return 0;
}

